 /*	
 *				
 *					ISNW ---- It is a war.It is not warcraft!
 *
 *
 *					Author:					zhoukeli(haxixi_keli)
 *					Filename:				SkinnedMesh.h
 *					CreateTime:				2008/12/19
 *					ModifyTime:				2008/12/19
 *
 */

#ifndef __SKINNEDMESH_H__
#define __SKINNEDMESH_H__

#include "include/ISkinnedMesh.h"
#include "MeshBuffer.h"

namespace ISNW
{
namespace scene
{
	class SkinnedMesh : public ISkinnedMesh
	{
	public:
		//! create joint
		joint* createjoint(joint* parent);

		//! get all joint
		core::array<joint*>& getalljoints();

		//! get joint
		const joint* getjoint(u32 idx) const;

		joint* getjoint(u32 idx);

		//! get all joint
		const core::array<joint*>& getalljoints() const;

		//! create weight
		weight* createweight(joint* j);

		//! get all weight
		core::array<weight>& getallweight(joint* j);

		//! create position key
		positionkey* createpositionkey(joint* j);

		//! create scale key
		scalekey* createscalekey(joint* j);

		//! create rotation key
		rotationkey* createrotationkey(joint* j);

		//! create mesh buffer
		MeshBuffer* createmeshbuffer();

		//! get all mesh buffer
		const core::array<MeshBuffer*>& getallbuffer() const;

		//! get all mesh buffer
		core::array<MeshBuffer*>& getallbuffer();

		//! get frame num
		virtual u32 getframenum() const;

		//! get mesh buffer count
		virtual s32 getmeshbuffercount() const;

		//! get mesh buffer by index
		virtual const IMeshBuffer* getmeshbuffer(s32 idx) const;

		virtual IMeshBuffer* getmeshbuffer(s32 idx);

		//! get bound box
		virtual const core::aabbox3df getboundbox() const{return core::aabbox3df();}

		//! set bound box
		virtual const core::aabbox3df setboundbox(const core::aabbox3d<f32>& box){return core::aabbox3df();}

		//! animate
		virtual void animate(u32 frame);

		//! after loaded,this method should be called
		void finalize();

	protected:
		void generateAllMatrix(u32 frame);

		void calculateMatrix(joint* j,joint* parent);

		void calculateAnimateMatrix(joint* j,joint* parent,u32 frame);

		void animatejoint(joint* j,u32 frame);

	public:
		//!members
		core::array<joint*>			joints;

		//! joint who has no parent
		core::array<joint*>			rootjoints;

		core::array<MeshBuffer*>	meshbuffers;

		u32							lastAnimateFrame;
	};
} // end namespace scene
} // end namespace ISNW
#endif